// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

/*
	Package unsafe contains operations that step around the type safety of Go programs.

	Packages that import unsafe may be non-portable and are not protected by the
	Go 1 compatibility guidelines.
*/
package unsafe

// 此处的任意类型仅用于文档编制，实际上不是不安全软件包的一部分。它表示任意Go表达式的类型。
type ArbitraryType int

// IntegerType仅用于文档编制，实际上不是不安全软件包的一部分。它表示任意整数类型。
type IntegerType int

// 指针表示指向任意类型的指针。类型指针有四个特殊操作
// 可用于其他类型的指针：
// -任何类型的指针值都可以转换为指针。
// /-指针可以转换为任何类型的指针值。
// /-uintptr可以转换为指针。
// /-指针可以转换为uintptr。
// 因此，指针允许程序击败类型系统并读取和写入
// 任意内存。使用时应格外小心。
// 
// 以下涉及指针的模式是有效的。
// 不使用这些模式的代码今天可能无效
// 或者将来可能无效。
// 即使是下面的有效模式也有重要的注意事项。
// 
// 运行“go-vet”可以帮助找到不符合这些模式的指针用法，但“go-vet”的沉默并不能保证代码有效。
// 
// （1）将*T1转换为指向*T2的指针。
// 
// 如果T2不大于T1，并且两者共享等效的
// 内存布局，则此转换允许将一种类型的数据重新解释为另一种类型的
// 数据。
// math的实现就是一个例子。浮点64位：
// 
// func浮点64位（f浮点64）uint64{
// return*（*uint64）（不安全的指针（&f））
// }
// 
// （2）指针到uintptr的转换（但不返回指针）。
// 
// 将指针转换为uintptr将生成指向的值
// 的内存地址，该值为整数。这种uintptr通常用于打印。
// 
// 将uintptr转换回指针通常无效。
// 
// uintptr是一个整数，而不是一个引用。
// 将指针转换为uintptr将创建一个整数值
// 不带指针语义。
// 即使uintptr持有某个对象的地址，
// 如果对象移动，垃圾收集器也不会更新该uintptr的值
// 也不会阻止对象
// 被回收。
// 
// 剩下的模式列举了从uintptr到指针的唯一有效转换
// 。
// 
// （3）指针指向uintptr并返回的转换，带有算术运算。
// 
// 如果p指向一个已分配的对象，它可以通过对象
// 通过转换为uintptr、添加偏移量并转换回指针来前进。
// 
// p=不安全。指针（uintptpr（p）+offset）
// 
// 此模式最常用于访问结构中的字段
// 或数组元素：
// 
// /相当于f:=不安全。指针（&s.f）
// f:=不安全。指针（uintptr（unsafe.Pointer&s））+不安全。偏移量（s.f）
// 
// /相当于e:=不安全。指针（&x[i]）
// e:=不安全。指针（uintptr（unsafe.Pointer（&x[0]））+i*unsafe。Sizeof（x[0]）
// 
// 以这种方式对指针的偏移量进行加和减都是有效的。
// 使用&^来圆化指针也是有效的，通常用于对齐。
// 在所有情况下，结果必须继续指向原始分配的对象。
// 
// 与C语言不同，将指针向前移到
// 其原始分配之外是无效的：
// 
// 
// var s thing 
// end=不安全。指针（uintptr（unsafe.Pointer&s））+不安全。Sizeof（s））
// 
// /无效：端点超出分配的空间。
// b:=make（[]字节，n）
// 结束=不安全。指针（uintptpr（unsafe.Pointer（&b[0]）+uintptpr（n））
// 
// 请注意，两个转换必须出现在同一个表达式中，只有
// 它们之间的中间运算：
// 
// 
// 
// u:=uintpttr（p）
// p=不安全。指针（u+偏移量）
// 
// 请注意，指针必须指向已分配的对象，因此它可能不是零。
// 
// /无效：零指针的转换
// /u:=不安全。指针（nil）
// p:=不安全。指针（uintptr（u）+偏移量）
// 
// （4）调用syscall时指针到uintptr的转换。系统调用。
// 
// 包Syscall中的Syscall函数直接将其uintptr参数
// 传递给操作系统，然后根据调用的详细信息，操作系统可能会将其中一些参数重新解释为指针。
// 也就是说，系统调用实现隐式地将某些参数
// 从uintptr转换回指针。
// 
// 如果必须将指针参数转换为uintptr以用作参数，则
// 该转换必须出现在调用表达式本身中：
// 
// syscall。Syscall（SYS_READ，uintpttr（fd），uintpttr（unsafe.Pointer（p）），uintptpr（n））
// 
// 编译器在
// 的参数列表中处理一个转换为uintptr的指针。通过安排被引用的
// 分配的对象（如果有的话）被保留，并且在调用完成之前不移动，
// 即使仅从类型来看，调用期间似乎不再需要
// 对象。
// 
// 编译器要识别此模式，
// 转换必须出现在参数列表中：
// 
// 
// 。
// u:=uintpttr（unsafe.Pointer（p））
// syscall。Syscall（SYS_READ，uintpttr（fd），u，uintpttr（n））
// 
// （5）反射结果的转换。价值指针或反射。价值UnsafeAddr 
// 从uintptr到指针。
// 
// Package reflect名为指针的值方法和UnsafeAddr返回类型uintptr 
// 而不是不安全的。防止调用者在不首先导入“不安全”的情况下将结果更改为任意
// 类型的指针。但是，这意味着结果是
// 脆弱的，必须在发出调用后立即转换为指针，
// 使用相同的表达式：
// 
// p:=（*int）（不安全的.Pointer（reflect.ValueOf（new（int））。指针（））
// 
// 与上述情况一样，在转换前存储结果是无效的：
// 
// /无效：在转换回指针之前，uintptr不能存储在变量
// /中。
// u:=反映。ValueOf（新的（int））。指针（）
// p:=（*int）（unsafe.Pointer（u））
// 
// （6）反射的转换。切片或反射。指向或来自指针的StringHeader数据字段。
// 
// 与前一种情况一样，reflect数据结构SliceHeader和StringHeader 
// 将字段数据声明为uintptr，以防止调用者在不首先导入“不安全”的情况下将结果更改为
// 任意类型。然而，这意味着只有在解释实际切片或字符串值的内容
// SliceHeader和StringHeader才有效。
// 时，
// 
// var s string 
// hdr:=（*reflect.StringHeader）（unsafe.Pointer（&s））
// hdr。Data=uintpttr（unsafe.Pointer（p））
// hdr。Len=n 
// 
// 在这个用法中hdr。数据实际上是引用字符串头中的底层
// 指针的另一种方式，而不是uintptr变量本身。
// 
// 总的来说，反映。切片头和反射。StringHeader只能用作*reflect。切片头和*反射。StringHeader指向实际的
// 切片或字符串，而不是普通结构。
// 程序不应声明或分配这些结构类型的变量。
// 
// /无效：直接声明的头将不包含作为引用的数据。
// var hdr reflect。StringHeader 
// hdr。Data=uintpttr（不安全的指针（p））
// hdr。Len=n 
// s:=*（*string）（unsafe.Pointer（&hdr））
// 
type Pointer *ArbitraryType

// Sizeof接受任何类型的表达式x，并返回假设变量v的大小（字节），就好像v是通过var v=x声明的一样。
// 该大小不包括x可能引用的任何内存。
// 例如，如果x是一个片，Sizeof返回片
// 描述符的大小，而不是片引用的内存大小。
// Sizeof的返回值是一个Go常量。
func Sizeof(x ArbitraryType) uintptr

// Offsetof返回由x表示的字段的结构内的偏移量，
// 其形式必须为structValue。领域换句话说，它返回结构开头和字段开头之间的字节数。
// Offsetof的返回值是一个Go常量。
func Offsetof(x ArbitraryType) uintptr

// Alignof接受任何类型的表达式x，并返回假设变量v所需的对齐方式
// 就像v是通过var v=x声明的一样。
// 它是最大的值m，因此v的地址始终为零mod m。
// 它与reflect返回的值相同。类型（x）。对齐（）。
// 作为一种特殊情况，如果变量s是结构类型，而f是该结构中的字段
// 则Alignof（s.f）将返回结构中该类型字段所需的对齐方式
// 。本例与reflect返回的
// 值相同。类型（s.f.）。FieldAlign（）。
// Alignof的返回值是一个Go常量。
func Alignof(x ArbitraryType) uintptr

// 函数Add将len添加到ptr并返回更新的指针
// 指针（uintpttr（ptr）+uintpttr（len））。
// len参数必须是整型或非整型常量。
// 常数len参数必须由int类型的值表示；
// 如果它是一个非类型化的常量，则被赋予int类型。
// 指针的有效使用规则仍然适用。
func Add(ptr Pointer, len IntegerType) Pointer

// 函数切片返回一个切片，其底层数组从ptr 
// 开始，其长度和容量为len。
// Slice（ptr，len）相当于
// 
// （*[len]任意类型）（unsafe.Pointer（ptr））[：]
// 
// ，但作为特例，如果ptr为零，
// Slice返回零。
// 
// len参数必须是整型或非整型常量。
// 常数len参数必须是非负的，并且可以用int类型的值表示；
// 如果它是一个非类型化常量，则在运行时指定int类型。
// 如果len为负，或者如果ptr为零且len不为零，则会发生运行时恐慌。
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
